#include <algorithm>
#include "component_impl.hh"
#include "../corelib/util/string_util.hh"

namespace kratos { namespace engine {

ComponentManagerImpl::ComponentManagerImpl() {
}

ComponentManagerImpl::~ComponentManagerImpl() {
}

void ComponentManagerImpl::update() {
}

bool ComponentManagerImpl::registerComponent(Component* ptr) {
    if (!ptr) {
        return false;
    }
    auto it = componentMap_.find(ptr->getName());
    if (it != componentMap_.end()) {
        return false;
    }
    componentMap_.emplace(ptr->getName(), 
        std::shared_ptr<Component>(ptr, std::bind(&ComponentManagerImpl::release, this, std::placeholders::_1)));
    return true;
}

bool ComponentManagerImpl::unregisterComponent(const std::string& name) {
    auto it = componentMap_.find(name);
    if (it == componentMap_.end()) {
        return false;
    }
    it->second->onErase();
    componentMap_.erase(it);
    return true;
}

std::shared_ptr<Component> ComponentManagerImpl::get(const std::string & name) {
    return getRoot(name);
}

std::shared_ptr<Component> ComponentManagerImpl::getRoot(const std::string & name) {
    auto it = componentMap_.find(name);
    if (it == componentMap_.end()) {
        return nullptr;
    }
    return it->second;
}

void ComponentManagerImpl::release(Component* ptr) {
    if (ptr->getFactory()) {
        ptr->getFactory()->destroy(ptr);
    }
}

}}
